﻿// ===============================================================================
//  Copyright © ymind.net. All rights reserved .
//  官方网站：http://ymind.net/
//  版权所有：彦铭工作室 老陈出品
// ===============================================================================

using System;
using System.Runtime.InteropServices;

namespace Lcsoft.TemplateEngine.Core
{
	/// <summary>
	/// 表示正在使用老陈Asp.Net模板引擎的应用程序的信息。
	/// </summary>
	[ComVisible(true)]
	[Serializable]
	public struct ApplicationInfo
	{
		private static readonly bool _emptyValueFilled;

		static ApplicationInfo()
		{
			Empty = new ApplicationInfo(Guid.Empty, String.Empty, String.Empty, new Version(), DateTime.MinValue, String.Empty, String.Empty, String.Empty, String.Empty);

			_emptyValueFilled = true;

			YMind = new ApplicationInfo(new Guid("D797F30F-DA2F-4769-B5A1-DCA1FC5A9BB3"), "老陈Asp.Net模板引擎", "Lcsoft.TemplateEngine For Asp.Net(C#)", TemplateEngineHelper.Version, TemplateEngineHelper.ProductDate, "http://www.ymind.net/", "http://www.ymind.net/", "彦铭工作室", "YMind Chan");
		}

		/// <summary>
		/// 初始化 <see cref="ApplicationInfo"/> 类的新实例。
		/// </summary>
		/// <param name="guid">指定应用程序的全局唯一标识符。</param>
		/// <param name="productName">指定应用程序的产品名称。</param>
		/// <param name="productEnglishName">指定应用程序的产品名称的英文表示。</param>
		/// <param name="productVersion">指定应用程序的版本信息。</param>
		/// <param name="productDate">指定应用程序的发布日期。</param>
		/// <param name="homePage">指定应用程序的主页链接地址。</param>
		/// <param name="supportPage">指定应用程序的技术支持链接地址。</param>
		/// <param name="copyrightHolder">指定应用程序的版权所有者。</param>
		/// <param name="author">指定应用程序的作者。</param>
		public ApplicationInfo(Guid guid, string productName, string productEnglishName, Version productVersion, DateTime productDate, string homePage, string supportPage, string copyrightHolder, string author) : this()
		{
			if (_emptyValueFilled)
			{
				if (guid == Guid.Empty) throw new ArgumentOutOfRangeException("guid", "guid 的值不能为 Guid.Empty。");

				if (productName == null) throw new ArgumentNullException("productName");
				if (productName.Length == 0) throw new ArgumentOutOfRangeException("productName");

				if (productEnglishName == null) throw new ArgumentNullException("productEnglishName");
				if (productEnglishName.Length == 0) throw new ArgumentOutOfRangeException("productEnglishName");

				if (productVersion == null) throw new ArgumentNullException("productVersion");

				if (homePage == null) throw new ArgumentNullException("homePage");
				if (homePage.Length == 0) throw new ArgumentOutOfRangeException("homePage");

				if (supportPage == null) throw new ArgumentNullException("supportPage");
				if (supportPage.Length == 0) throw new ArgumentOutOfRangeException("supportPage");

				if (copyrightHolder == null) throw new ArgumentNullException("copyrightHolder");
				if (copyrightHolder.Length == 0) throw new ArgumentOutOfRangeException("copyrightHolder");

				if (author == null) throw new ArgumentNullException("author");
				if (author.Length == 0) throw new ArgumentOutOfRangeException("author");
			}

			this.Guid = guid;
			this.ProductName = productName;
			this.Name = productEnglishName;
			this.Version = productVersion;
			this.ProductDate = productDate;
			this.HomePage = homePage;
			this.SupportPage = supportPage;
			this.CopyrightHolder = copyrightHolder;
			this.Author = author;
		}

		/// <summary>
		/// 获取一个不包含任何内容的应用程序信息的实例。
		/// </summary>
		public static ApplicationInfo Empty { get; private set; }

		/// <summary>
		/// 获取包含老陈Asp.Net模板引擎默认应用程序信息的实例。
		/// </summary>
		public static ApplicationInfo YMind { get; private set; }

		/// <summary>
		/// 获取应用程序的全局唯一标识符。
		/// </summary>
		public Guid Guid { get; private set; }

		/// <summary>
		/// 获取应用程序的产品名称。
		/// </summary>
		public string ProductName { get; private set; }

		/// <summary>
		/// 获取应用程序的产品友好名称。
		/// </summary>
		public string Name { get; private set; }

		/// <summary>
		/// 获取应用程序的版本信息。
		/// </summary>
		public Version Version { get; private set; }

		/// <summary>
		/// 获取应用程序的发布日期。
		/// </summary>
		public DateTime ProductDate { get; private set; }

		/// <summary>
		/// 获取应用程序的主页链接地址。
		/// </summary>
		public string HomePage { get; private set; }

		/// <summary>
		/// 获取应用程序的技术支持链接地址。
		/// </summary>
		public string SupportPage { get; private set; }

		/// <summary>
		/// 获取应用程序的版权所有者。
		/// </summary>
		public string CopyrightHolder { get; private set; }

		/// <summary>
		/// 获取应用程序的作者。
		/// </summary>
		public string Author { get; private set; }

		/// <summary>
		/// 确定两个 <see cref="ApplicationInfo"/> 对象是否不相等。
		/// </summary>
		/// <param name="a1">第一个 <see cref="ApplicationInfo"/> 对象。</param>
		/// <param name="a2">第二个 <see cref="ApplicationInfo"/> 对象。</param>
		/// <returns>如果 <paramref name="a1"/> 不等于 <paramref name="a2"/>，则为 true；否则为 false。</returns>
		public static bool operator !=(ApplicationInfo a1, ApplicationInfo a2) { return !(a1 == a2); }

		/// <summary>
		/// 确定两个 <see cref="ApplicationInfo"/> 对象是否相等。
		/// </summary>
		/// <param name="a1">第一个 <see cref="ApplicationInfo"/> 对象。</param>
		/// <param name="a2">第二个 <see cref="ApplicationInfo"/> 对象。</param>
		/// <returns>如果 <paramref name="a1"/> 等于 <paramref name="a2"/>，则为 true；否则为 false。</returns>
		public static bool operator ==(ApplicationInfo a1, ApplicationInfo a2) { return a1.Guid == a2.Guid && a1.ProductName == a2.ProductName && a1.Name == a2.Name && a1.Version == a2.Version && a1.ProductDate == a2.ProductDate && a1.HomePage == a2.HomePage && a1.SupportPage == a2.SupportPage && a1.CopyrightHolder == a2.CopyrightHolder && a1.Author == a2.Author; }

		/// <summary>
		/// 指示此实例与指定对象是否相等。
		/// </summary>
		/// <param name="obj">要比较的另一个对象。</param>
		/// <returns>如果 <paramref name="obj"/> 和该实例具有相同的类型并表示相同的值，则为 true；否则为 false。</returns>
		public override bool Equals(object obj) { return obj is ApplicationInfo && this == (ApplicationInfo)obj; }

		/// <summary>
		/// 返回此实例的哈希代码。
		/// </summary>
		/// <returns>一个 32 位有符号整数，它是该实例的哈希代码。</returns>
		public override int GetHashCode() { return this.Guid.GetHashCode() ^ this.ProductName.GetHashCode() ^ this.Version.GetHashCode() ^ this.Author.GetHashCode(); }

		/// <summary>
		/// 返回表示此实例的字符串形式。
		/// </summary>
		/// <returns>包含此实例的信息的字符串。</returns>
		public override string ToString() { return String.Format("{0} Version {1}", this.ProductName, this.Version); }
	}
}
